package org.example.collection;

import org.junit.Test;

import java.util.Vector;
import java.util.concurrent.TimeUnit;

/**
 * Vector 类可以实现可增长的对象数组，与数组一样，它包含可以使用整数索引进行访问的组件，Vector 的大小可以根据需要增大或缩小，以适应创建 Vector 后进行添加或移除项的操作。
 * Vector 是同步的，它在方法上设置了 synchronized 关键字，添加了 对象锁。
 * Vector 大致相当于 ArrayList，不同之处在 Vector 是线程安全的，而 ArrayList 是线程不安全的。
 * 当需要扩容时,Vector 默认增长为原来一培，而 ArrayList 却是原来的一半。
 *
 * @author wangMaoXiong
 * @version 1.0
 * @date 2021/8/6 8:57
 */
@SuppressWarnings("all")
public class VectorTest {

    /**
     * Vector 使用等同于 ArrayList
     */
    @Test
    public void testVector1() {
        Vector<Integer> vector = new Vector();
        for (int i = 1; i <= 10; i++) {
            vector.add(i);
        }
        System.out.println(vector);//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

        for (int i = 0; i < vector.size(); ) {
            Integer remove = vector.remove(i);
            //1	2	3	4	5	6	7	8	9	10
            System.out.print(remove + "\t");
        }
    }

    /**
     * 验证 vector 的并发线程安全
     * 1、假设有 1000 个号(total=1000)，由50个窗口(windows=50)同时卖，每个窗口卖规定卖20个号.
     * 2、最后得结果如果是 CopyOnWriteArrayList 为空，且各个线程没有卖重复的号，则说明并发正常.
     * 3、如果换成 ArrayList ，则立马出现错误数据.
     */
    @Test
    public void testvector2() {
        Vector<Integer> vector = new Vector();
        int total = 1000;
        int windows = 50;
        int count = 20;

        for (int i = 1; i <= total; i++) {
            vector.add(i);
        }

        for (int i = 1; i <= windows; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        int i = 0;
                        while (i++ < count) {
                            Object remove = vector.remove(0);
                            System.out.println(Thread.currentThread().getName() + ":" + remove);
                            Thread.sleep(200);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(vector);//[]
    }

}
